package com.fandou.base.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.util.AttributeSet;

import androidx.annotation.DrawableRes;
import androidx.appcompat.widget.AppCompatImageView;

import com.fandou.base.R;

public class CornerImageView extends AppCompatImageView {
	private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
	private static final int COLOR_DRAWABLE_DIMENSION = 2;

	private float leftTopRadius;
	private float leftBottomRadius;
	private float rightTopRadius;
	private float rightBottomRadius;

	private Bitmap mBitmap;
	private final Paint mBitmapPaint = new Paint();
	{
		mBitmapPaint.setColor(Color.TRANSPARENT);
	}
	private int mBitmapWidth;
	private int mBitmapHeight;

	private boolean mReady;
	private boolean mSetupPending;

	private boolean bSizeSet = false;

	public CornerImageView(Context context) {
		super(context);
		init(null);
	}

	public CornerImageView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init(attrs);
	}

	public CornerImageView(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);
		init(attrs);
	}

	private void init(AttributeSet attrs) {
		mReady = true;

		TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.CornerImageView);
		float allRadius = typedArray.getDimension(R.styleable.CornerImageView_allRadius, -1);
		if (allRadius >= 0) {
			leftTopRadius = allRadius;
			rightTopRadius = allRadius;
			leftBottomRadius = allRadius;
			rightBottomRadius = allRadius;
		} else {
			leftTopRadius = typedArray.getDimension(R.styleable.CornerImageView_leftTopRadius, 0);
			rightTopRadius = typedArray.getDimension(R.styleable.CornerImageView_rightTopRadius, 0);
			leftBottomRadius = typedArray.getDimension(R.styleable.CornerImageView_leftBottomRadius, 0);
			rightBottomRadius = typedArray.getDimension(R.styleable.CornerImageView_rightBottomRadius, 0);
		}

		if (mSetupPending) {
			setup();
			mSetupPending = false;
		}
	}

	public void setRadius(int leftTop, int rightTop, int leftBottom, int rightBottom) {
		leftTopRadius = leftTop;
		rightTopRadius = rightTop;
		leftBottomRadius = leftBottom;
		rightBottomRadius = rightBottom;
		setup();
	}

	@Override
	public void setImageBitmap(Bitmap bm) {
		super.setImageBitmap(bm);
		mBitmap = bm;
		setup();
	}

	@Override
	public void setImageDrawable(Drawable drawable) {
		super.setImageDrawable(drawable);
		mBitmap = getBitmapFromDrawable(drawable);
		setup();
	}

	@Override
	public void setImageResource(@DrawableRes int resId) {
		super.setImageResource(resId);
		mBitmap = getBitmapFromDrawable(getDrawable());
		setup();
	}

	@Override
	public void setImageURI(Uri uri) {
		super.setImageURI(uri);
		mBitmap = uri != null ? getBitmapFromDrawable(getDrawable()) : null;
		setup();
	}

	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//		log("onMeasure: MeasureSize = " + getMeasuredWidth() + " x " + getMeasuredHeight());
//		log("onMeasure before: mBitmap = " + mBitmapWidth + " x " + mBitmapHeight);
		if (mBitmapWidth == 0 || mBitmapHeight == 0) {
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);
			return;
		}
//		log("onMeasure: MeasureSpec = " + widthMeasureSpec + " x " + heightMeasureSpec);
		int width = MeasureSpec.getSize(widthMeasureSpec);
		int height = MeasureSpec.getSize(heightMeasureSpec);

//		log("onMeasure: MeasureSpec.getSize = " + width + " x " + height);

		if (width == 0 && height == 0) {
			width = mBitmapWidth;
			height = mBitmapHeight;
		} else if (width == 0 || (height > 0 && width * mBitmapHeight > height * mBitmapWidth)) {
			width = height * mBitmapWidth / mBitmapHeight;
		} else {
			height = width * mBitmapHeight / mBitmapWidth;
		}

//		log("onMeasure: size = " + width + " x " + height);
		setMeasuredDimension(width, height);
	}

	@Override
	protected void onDraw(Canvas canvas) {
		if (mBitmap == null) {
			return;
		}

		Path path = new Path();
		path.moveTo(0, leftTopRadius);
		path.quadTo(0, 0, leftTopRadius, 0);
		path.lineTo(getWidth() - rightTopRadius, 0);
		path.quadTo(getWidth(), 0, getWidth(), rightTopRadius);
		path.lineTo(getWidth(), getHeight() - rightBottomRadius);
		path.quadTo(getWidth(), getHeight(), getWidth() - rightBottomRadius, getHeight());
		path.lineTo(leftBottomRadius, getHeight());
		path.quadTo(0, getHeight(), 0, getHeight() - leftBottomRadius);
		path.lineTo(0, leftTopRadius);

		canvas.clipPath(path);

		super.onDraw(canvas);
	}

	public void setSize(int width, int height) {
		this.mBitmapWidth = width;
		this.mBitmapHeight = height;
		bSizeSet = true;
	}

	private void setup() {
		if (!mReady) {
			mSetupPending = true;
			return;
		}
		if (!bSizeSet) {
			if (mBitmap == null) {
				return;
			}

			mBitmapWidth = mBitmap.getWidth();
			mBitmapHeight = mBitmap.getHeight();
		}

		mBitmapPaint.setAntiAlias(true);

		requestLayout();
//		invalidate();
	}

	private Bitmap getBitmapFromDrawable(Drawable drawable) {
		if (drawable == null) {
			return null;
		}

		if (drawable instanceof BitmapDrawable) {
			return ((BitmapDrawable) drawable).getBitmap();
		}

		try {
			Bitmap bitmap;

			if (drawable instanceof ColorDrawable) {
				bitmap = Bitmap.createBitmap(COLOR_DRAWABLE_DIMENSION, COLOR_DRAWABLE_DIMENSION, BITMAP_CONFIG);
			} else {
				bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
			}

			Canvas canvas = new Canvas(bitmap);
			drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
			drawable.draw(canvas);
			return bitmap;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}
